package win.skxe07.quartz;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 计划任务管理
 * @author DIY
 * 2018年5月16日  下午5:55:52
 */
@Service
public class QuartzManager {
	public final Logger log = Logger.getLogger(this.getClass());
	
	@Autowired
	private Scheduler scheduler;

	/**
	 * 添加任务
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	
	public void addJob(ScheduleJob job) {
		
		try {
			// 创建jobDetail实例，绑定Job实现类
			// 指明job的名称，所在组的名称，以及绑定job类
			JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class)
											.withIdentity(job.getJobKey())
//											.withIdentity(job.getJobName(), job.getJobGroup()) //2选1
											.usingJobData(job.getDataMap())
											.build();
			// 定义调度触发规则
			// 使用cornTrigger规则
			Trigger trigger = TriggerBuilder.newTrigger()
											.withIdentity(job.getJobName(), job.getJobGroup())// 触发器key
											.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
											.startNow()
											.build();
			// 把作业和触发器注册到任务调度中
			scheduler.scheduleJob(jobDetail, trigger);
			// 判断调度器是否启动
			if (!scheduler.isStarted()) {
				scheduler.start();
			}
			log.info(String.format("定时任务:%s.%s-已添加到调度器!", job.getJobGroup(),job.getJobName()));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取所有计划中的任务列表
	 * 
	 * @return
	 * @throws SchedulerException
	 */
	public List<ScheduleJob> getAllJob() throws SchedulerException {
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
		List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
		for (JobKey jobKey : jobKeys) {
			ScheduleJob job  = ScheduleJob.getJobFromMap(scheduler.getJobDetail(jobKey).getJobDataMap());
			jobList.add(job);
		}
		return jobList;
	}

	/**
	 * 所有正在运行的job
	 * 
	 * @return
	 * @throws SchedulerException
	 */
	public List<ScheduleJob> getRunningJob() throws SchedulerException {
		List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
		List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
		for (JobExecutionContext executingJob : executingJobs) {
			ScheduleJob job  = ScheduleJob.getJobFromMap(executingJob.getJobDetail().getJobDataMap());
			jobList.add(job);
		}
		return jobList;
	}

	/**
	 * 暂停一个job
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void pauseJob(ScheduleJob job) throws SchedulerException {
		scheduler.pauseJob(job.getJobKey());
		log.info(String.format("定时任务:%s.%s-已暂停!", job.getJobGroup(),job.getJobName()));
	}

	/**
	 * 恢复一个job
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void resumeJob(ScheduleJob job) throws SchedulerException {
		scheduler.resumeJob(job.getJobKey());
		log.info(String.format("定时任务:%s.%s-已重启!", job.getJobGroup(),job.getJobName()));
	}

	/**
	 * 删除一个job
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void deleteJob(ScheduleJob job) throws SchedulerException {
		scheduler.deleteJob(job.getJobKey());
		log.info(String.format("定时任务:%s.%s-已删除!", job.getJobGroup(),job.getJobName()));
	}

	/**
	 * 立即执行job
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void runAJobNow(ScheduleJob job) throws SchedulerException {
		scheduler.triggerJob(job.getJobKey());
		log.info(String.format("定时任务:%s.%s-立即启动!", job.getJobGroup(),job.getJobName()));
	}

	/**
	 * 更新job时间表达式
	 * 
	 * @param job
	 * @throws SchedulerException
	 */
	public void updateJobCron(ScheduleJob job) throws SchedulerException {

		TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());

		CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

		trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

		scheduler.rescheduleJob(triggerKey, trigger);
		log.info(String.format("定时任务:%s.%s-更换新的执行时间["+job.getCronExpression()+"]!", job.getJobGroup(),job.getJobName()));
	}
	
	public TriggerState jobIsRun(ScheduleJob job){
		TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup()); 
		try {
			return scheduler.getTriggerState(triggerKey);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		return null;
	}
}